package com.lin.generate.config.datasource;

import com.lin.generate.common.utill.SessionUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @description TODO
 * @Author: z156940l@outlook.com
 * @className DataConfigInterceptor
 * @Date: 2023/6/1 23:19
 */
@Aspect
@Order(1)
@Component
public class DataConfigInterceptor {

    @Before("execution(* com.lin.generate.service..*.*(..))")
    // 如果项目分了模块的话就这样写：@Before("execution(* com.lin.generate..service..*.*(..))")
    public void beforeSwitchDS(JoinPoint point) throws Exception {
        DataSourceBean db = SessionUtil.getDataSourceBean();
        if (db == null) {
            db = DataSourceComponent.getDataSourceBean();
        }
        if (db != null) {
            DataSourceConfig.chageDB(db);
        }
        dataSourceSelector(point);
    }

    @After("execution(* com.lin.generate.service..*.*(..))")
    public void afterSwitchDS(JoinPoint point){
        DynamicDataSourceContextHolder.clearDB();
        DynamicDataSourceContextHolder.clearCompany();
    }

    /**
     * point是否有@DataSourceSelector注解并切换到参数对应数据源
     * @param point
     */
    public void dataSourceSelector(JoinPoint point) {
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();

        //获得访问的方法名
        String methodName = point.getSignature().getName();
        //得到方法的参数的类型
        Class<?>[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
        String dataSource = DynamicDataSourceContextHolder.getDB();
        try {
            // 得到访问的方法对象
            Method method = className.getMethod(methodName, argClass);

            // 判断是否存在@DS注解
            if (method.isAnnotationPresent(DataSourceSelector.class)) {
                DataSourceSelector annotation = method.getAnnotation(DataSourceSelector.class);
                // 取出注解中的数据源名
                dataSource = annotation.value().getDatasourceName();
                // 切换数据源
                DynamicDataSourceContextHolder.setDB(dataSource);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
